package com.hxzy.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.util.concurrent.AtomicDouble;
import com.hxzy.common.enums.AckCode;
import com.hxzy.common.exception.ServiceException;
import com.hxzy.common.exception.ServiceStringException;
import com.hxzy.common.util.MarketingThreadLocalUtil;
import com.hxzy.controller.mobile.cart.resp.MobileCartResp;
import com.hxzy.controller.mobile.login.resp.MobileLoginResp;
import com.hxzy.controller.mobile.order.req.OrderCreateReq;
import com.hxzy.entity.*;
import com.hxzy.service.*;
import com.hxzy.mapper.OrdersMapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;

/**
* @author 11452
* @description 针对表【orders(订单表)】的数据库操作Service实现
* @createDate 2023-08-28 11:54:55
*/
@Log4j2
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders>
    implements OrdersService{

    @Autowired
    private ShoppingCartService shoppingCartService;

    @Autowired
    private ProductService productService;

    @Autowired
    private AddressBookService addressBookService;

    @Autowired
    private OrderDetailService  orderDetailService;

    /**
     * 创建订单
     * @param req
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String createOrder(OrderCreateReq req) {
        //1、当前用户是谁
        MobileLoginResp mobileLoginResp = MarketingThreadLocalUtil.mobileThreadLocal.get();
        Integer userId = mobileLoginResp.getId();

        //2、查询收货人信息
        AddressBook addressBook = this.addressBookService.getById(req.getAddressBookId());

        if(Objects.isNull(addressBook)){
            log.error( "收货人信息不存在");
            throw new ServiceStringException("收货人信息不存在");
        }

        //2、当前用户购物车这个商家的所有数据
        List<MobileCartResp> mobileCartRespList = this.shoppingCartService.findByMerchantId(req.getMerchantId());

        //3、创建订单信息 (几十万商家)
        Orders  newOrders=new Orders();
        String mid=StrUtil.padPre(req.getMerchantId()+"",6,"0");
        newOrders.setNumber(IdUtil.getSnowflakeNextIdStr()+mid);
        //待付款
        newOrders.setStatus("1");
        newOrders.setUserId(Long.valueOf(userId));
        newOrders.setMerchantId(req.getMerchantId());
        newOrders.setOrderTime(new Date());
        //2支付宝
        newOrders.setPayMethod(req.getPayMethod()+"");
        newOrders.setRemark(req.getRemark());
        //收货地址
        newOrders.setAddressBookId(req.getAddressBookId());
        String address=addressBook.getProvinceName()+addressBook.getCityName()+addressBook.getDistrictName()+addressBook.getDetail();
        newOrders.setAddress(address);
        newOrders.setPhone(addressBook.getPhone());
        newOrders.setUserName(mobileLoginResp.getLoginId());
        newOrders.setConsignee(addressBook.getConsignee());

        //应收金额
        final AtomicDouble amount=new AtomicDouble(0);


        //4、记录订单明细
        List<OrderDetail>  orderDetailList=new ArrayList<>();

        //5、预检商品库存（加锁）
        mobileCartRespList.stream().forEach(cart-> {
            //查询商品，加锁
            Product product= this.productService.findbyIdLock(cart.getDishId());
            if(Objects.isNull(product)){
                log.error(cart.getDishId()+",不存在，不能创建定单");
                throw new ServiceException(AckCode.ORDER_CREATE_FAILED);
            }

            //判断是否是该商家的
            if(!cart.getMerchantId().equals(product.getMerchantId())){
                log.error(cart.getDishId()+","+cart.getMerchantId()+",商家对应值不对");
                throw new ServiceException(AckCode.ORDER_CREATE_FAILED);
            }

            //商品下架了
            if(product.getIsgrounding().equals("0")){
                log.error(cart.getDishId()+",商品下架了，不能创建订单");
                throw new ServiceStringException(cart.getName()+",商品下架了，不能创建订单");
            }

            //判断库存
            if(product.getNum()!=-1){
                //库存不足
                if(product.getNum()<cart.getNumber()){

                    log.error(cart.getDishId()+",商品库存不足");
                    throw new ServiceStringException(cart.getName()+"库存不足");
                }

                //先扣真实商品库存
                product.setNum(product.getNum()-cart.getNumber());
                this.productService.updateById(product);
            }

            //汇总金额
            double money=cart.getNumber() * product.getPrice();
            amount.addAndGet( money);

            //记录订单明细
            OrderDetail  orderDetail=new OrderDetail();
            orderDetail.setName(product.getName());
            orderDetail.setImage(product.getPicture());
            orderDetail.setDishId(product.getId());
            orderDetail.setMerchantId(product.getMerchantId());
            orderDetail.setDishFlavor(cart.getDishFlavor());
            orderDetail.setNumber(cart.getNumber());
            orderDetail.setAmount(BigDecimal.valueOf(money));
            orderDetailList.add(orderDetail);
        });

        //6、保存订单
        //应收金额赋值
        newOrders.setAmount(BigDecimal.valueOf(amount.get()));
         this.baseMapper.insert(newOrders);
        //7、上传订单明细
        //为订单明细赋值订单主键
        for (OrderDetail item:orderDetailList ) {
            item.setOrderId(newOrders.getId());
        }
        this.orderDetailService.saveBatch(orderDetailList);

        //8、清空购物车
        this.shoppingCartService.cleanCart(req.getMerchantId());


        //返回订单编号
        return newOrders.getNumber();
    }

    @Override
    public Orders findByNumber(String orderNumber) {
        LambdaQueryWrapper<Orders> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(Orders::getNumber,orderNumber);

        return this.getOne(queryWrapper);
    }

    @Override
    public int updatePayStatusByOrderId(String orderNumber, Date payDate, BigDecimal bigDecimal, String alipayTradeNo) {
        return this.baseMapper.updatePayStatusByOrderId(orderNumber,payDate,bigDecimal,alipayTradeNo);
    }

    @Override
    public int cancelCheckOutTime(String outTradeNo) {
        return this.baseMapper.cancelCheckOutTime(outTradeNo);
    }
}




